/* 
  Persistence-facade:
  - provides convenient methods for business-object-retrieval
  - delegates data-retrieval to SoapService-functions or gets the data from offline-storage if the request fails
*/

/*
 * constructor:
 * */
function Persistence(){
    this.soapService = new SoapService('../../business/services/soap_service_requesthandler.php', 'POST');
}

/*
* 01: Get all groups for WM2014.
* @return list of groups
* */
Persistence.prototype.getallGroupsForWM2014 = function(callback) {
    var result = this.soapService.getAllGroups();

    if (result != null) {
        var json = $.parseJSON(result);
        var groups = [];

        $.each(json.GetAvailGroupsResult.Group, function(key, value) {
            var group = new Group();
            group.setGroupName(this.groupName);
            group.setGroupId(this.groupID);
            group.setGroupOrderId(this.groupOrderID);
            groups[key] = group;
        });

        var database = new Database(function(){
            for (i in groups) {
                database.setGroup(groups[i]);
            }
        });

        callback(groups);
    } else {
        var database = new Database(function(){
            database.getAllGroups(callback);
        });
    }
}

/*
 * 02: Get all matches for selected date.
 * @param selectedDate currently selected date in the calendar-overview (date-format: YYYY-MM-DD)
 * @return list of matches
 * */
Persistence.prototype.getAllMatchesForSelectedDate = function(selectedDate, callback) {

    var dateParts = selectedDate.split("-");
    var dateTo = new Date();
    dateTo.setFullYear((dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]) + 1);
    dateToString = 
            dateTo.getFullYear() + '-'
            + ('0' + (dateTo.getMonth()+1)).slice(-2) + '-'
            + ('0' + dateTo.getDate()).slice(-2);
    var result = this.soapService.getMatchesBetween(selectedDate, dateToString);
    if (result != null) {
        var json = $.parseJSON(result);
        var matches = [];

        if($.isArray(json.GetMatchdataByLeagueDateTimeResult.Matchdata)){
            var persistenceObj = this;
            $.each(json.GetMatchdataByLeagueDateTimeResult.Matchdata, function(key, value) {
                matches[key] = persistenceObj.createMatch(value);
            });
        }else{
            if(json.GetMatchdataByLeagueDateTimeResult.Matchdata){
                matches[0] = this.createMatch(json.GetMatchdataByLeagueDateTimeResult.Matchdata);
            }
        }

        var database = new Database(function(){
            for (i in matches) {
                database.setMatch(matches[i]);
            }
        });

        callback(matches);
    } else {
        var database = new Database(function(){
            database.getAllMatchesForSelectedDate(selectedDate, callback);
        });
    }
}

/*
 * 03: Get detail information about a specific group.
 * @param groupId Id of the group being used
 * @return group
 * */
Persistence.prototype.getGroupById = function(groupId, groupOrderId, groupName, callback) {
    var result = this.soapService.getMatchdataForGroupType(groupOrderId);

    if (result != null) {
        var json = $.parseJSON(result);
        var group = new Group();
        var matches = [];
        var teams = [];

        /* Create and add matches. */
        if($.isArray(json.GetMatchdataByGroupLeagueSaisonResult.Matchdata)) {
            var persistenceObj = this;
            $.each(json.GetMatchdataByGroupLeagueSaisonResult.Matchdata, function(key, value) {
                /* Only add matches for this group since the SOAP-requests returns all matches for this group-type. */
                if (groupId == value.groupID) {
                    matches.push(persistenceObj.createMatch(value));

                    /* Only add teams once. */
                    if (persistenceObj.isTeamNew(value.idTeam1, teams)) {
                        teams.push(persistenceObj.createTeam1(value));
                    }

                    if (persistenceObj.isTeamNew(value.idTeam2, teams)) {
                        teams.push(persistenceObj.createTeam2(value));
                    }
                }
            });
        } else {
            var matchdata = json.GetMatchdataByGroupLeagueSaisonResult.Matchdata;

            /* Only add matches for this group since the SOAP-requests returns all matches for this group-type. */
            if (groupId == matchdata.groupID) {
                matches[0] = this.createMatch(matchdata);

                /* Only add teams once. */
                if (this.isTeamNew(matchdata.idTeam1, teams)) {
                    teams.push(this.createTeam1(matchdata));
                }

                if (this.isTeamNew(matchdata.idTeam2, teams)) {
                    teams.push(this.createTeam2(matchdata));
                }
            }
        }

        group.setMatches(matches);
        group.setTeams(teams);
        group.setGroupId(groupId);
        group.setGroupOrderId(groupOrderId);
        group.setGroupName(groupName);

        var database = new Database(function(){
            database.setGroup(group);
        });

        callback(group);
    } else {
        var database = new Database(function(){
            database.getGroupById(groupId, callback);
        });
    }
}

/*
* 04: Get match by matchId.
* @return match
* */
Persistence.prototype.getMatchByMatchId = function(matchId, callback) {
    var result = this.soapService.getMatch(matchId);

    if (result != null) {
        var json = $.parseJSON(result);
        matchResults = json.GetMatchByMatchIDResult;

        /* Define match */
        var match = this.createMatch(matchResults);

        /* score initialisation for comparison */
        var oldScoreTeam1 = 0;

        /* Add all goals to the match. */
        if(typeof matchResults.goals.Goal != 'undefined'){
           $.each(matchResults.goals.Goal, function(key, value) {
                var goal = new Goal();
                goal.setId(this.goalID);
                goal.setMatchId(match.getId());
                goal.setGoalMatchMinute(this.goalMatchMinute);
                goal.setGoalScoreTeam1(this.goalScoreTeam1);
                goal.setGoalScoreTeam2(this.goalScoreTeam2);

                /* Calculate which team scored the current goal (calculated by comparing current score vs old score). */
                if (this.goalScoreTeam1 > oldScoreTeam1) {
                    goal.setwhichTeamScoredCurrentGoal(1);
                    oldScoreTeam1 += 1;
                } else {
                    goal.setwhichTeamScoredCurrentGoal(2);
                }

                goal.setGoalGetterName(this.goalGetterName);
                goal.setGoalPenalty(this.goalPenalty);
                goal.setOwnGoal(this.goalOwnGoal);
                goal.setOvertime(this.goalOvertime);
                goal.setGoalComment(this.goalComment);
                match.addGoal(goal);
            }); 
        }
        
        var database = new Database(function(){
            database.setMatch(match);
        });

        callback(match);
    } else {
        var database = new Database(function(){
            database.getMatchById(matchId, callback);
        });
    }

}

/* Creates a new match.
* @param obj json-object which provides all necessary values
* @return match
* */
Persistence.prototype.createMatch = function(obj){
   var match = new Match();
   match.setId(obj.matchID);
   match.setStartDateTime(obj.matchDateTime);
   match.setTeam1(obj.nameTeam1);
   match.setTeam2(obj.nameTeam2);
   match.setTeam1Points(obj.pointsTeam1);
   match.setTeam2Points(obj.pointsTeam2);
    match.setCity(obj.location.locationCity);
   return match;
}

/* Creates a new team (values are retrieved from team1).
* @param obj json-object which provides all necessary values
* @return team
* */
Persistence.prototype.createTeam1 = function(obj){
   var team = new Team();
   team.setId(obj.idTeam1);
   team.setName(obj.nameTeam1);
   team.setScore(obj.pointsTeam1);
   return team;
}

/* Creates a new team (values are retrieved from team2).
* @param obj json-object which provides all necessary values
* @return team
* */
Persistence.prototype.createTeam2 = function(obj){
   var team = new Team();
   team.setId(obj.idTeam2);
   team.setName(obj.nameTeam2);
   team.setScore(obj.pointsTeam2);
   return team;
}

/* Performs a check if this team has been added to the list of teams for this group yet.
* @param teamId Id of the team to check
* @param teams array of teams the check is performed against
* @return true, if this team is not yet part of teams
* */
Persistence.prototype.isTeamNew = function(teamId, teams) {
   teamIds = [];

   for (var key in teams) {
       if (teamId == teams[key].getId()) {
           return false;
       }
   }
   return true;
}